#include "RstpGossip.h"
#include "SocketUtils.h"
#include "LogInterface.h"
#include "CommonOpt.h"


//////////////////////////////////////////////////////////////////////////
SFriendInfo::SFriendInfo()
{
	m_PeerID = 0;
	m_NatType = 0;
	m_InnerIP = 0;
	m_InnerPort = 0;
	m_OuterIP = 0;
	m_OuterPort = 0;
}

Int32 SFriendInfo::ParserStream(const char *inData, Int32 nDataLen)
{
	if(!inData || nDataLen <= 0)
		return 0;
	
	PacketHandler Handler(inData,nDataLen);
	Handler>>m_PeerID>>m_NatType>>m_InnerIP>>m_InnerPort>>m_OuterIP>>m_OuterPort;
	
	return Handler.Size();
}

Int32 SFriendInfo::MakeStream(char *ioBuf, Int32 nBufLen)
{
	if(ioBuf == NULL)
		return 0;
	
	PacketHandler Handler(ioBuf,nBufLen);
	Handler<<m_PeerID<<m_NatType<<m_InnerIP<<m_InnerPort<<m_OuterIP<<m_OuterPort;
	
	return Handler.Size();
}


//////////////////////////////////////////////////////////////////////////
//SGossipMsg
SGossipMsg& SGossipMsg::operator=(const SGossipMsg &other)
{
	if(this == &other)
		return *this;

	m_ChannelID = other.m_ChannelID;
	m_SenderPeerID = other.m_SenderPeerID;
	m_Flag = other.m_Flag;	
	m_BM = other.m_BM;
	
	m_FriendCount = other.m_FriendCount;
	m_pFriendsInfo = new SFriendInfo[m_FriendCount];
	memcpy(m_pFriendsInfo, other.m_pFriendsInfo, sizeof(SFriendInfo)*m_FriendCount);
	
	return *this;
}
Int32 SGossipMsg::ParserStream(const char *inData, Int32 nDataLen)
{
	if(!inData || nDataLen <= 0)
		return 0;

	const char *pCur = inData;
	
	PacketHandler Handler(pCur,nDataLen);
	Handler>>m_ChannelID>>m_SenderPeerID>>m_Flag;
	pCur += Handler.Size();

	Int32 iRet = 0;
	//copy PeerBM
	if(IsHasBmInfo())
	{
		Int32 iRet = m_BM.ParserData(pCur);
		pCur += iRet;
	}

	PacketHandler Handler2(pCur,nDataLen);
	Handler2>>m_FriendCount;
	pCur += Handler2.Size();
	
	if(m_FriendCount > 0)
	{
		m_pFriendsInfo = new SFriendInfo[m_FriendCount];
		if(m_pFriendsInfo == NULL)
			return 0;
		
		for(Int32 i=0; i<m_FriendCount; i++)
		{
			iRet = m_pFriendsInfo[i].ParserStream(pCur, nDataLen);
			if(iRet <= 0)
				return 0;
			
			pCur += iRet;
		}
	}
	
	return pCur - inData;
}

Int32 SGossipMsg::MakeStreamWithRstpHeade(char *ioBuf, Int32 nBufLen)
{
	struct SRstpCommHead CommH;
	UInt32 nLen = MakeStream(ioBuf + CommH.Size(), nBufLen -  CommH.Size());
	Assert(nLen > 0);
	
	///TODO Need to seperat
	CommH.DataLen = nLen + CommH.Size();
	CommH.ChnID = CHN_ID_GOSSIP;
	CommH.RequestID = (UInt16)-1;
	CommH.SeqNo = 0;
	CommH.Total = 1;
	CommH.OutAsData(ioBuf, CommH.Size());
	
	UInt32 nMsgLen = CommH.DataLen;
	return nMsgLen;
}

Int32 SGossipMsg::MakeStream(char *ioBuf, Int32 nBufLen)
{
	if(ioBuf == NULL)
		return 0;

	char *pCur = (char *)ioBuf;

	PacketHandler Handler(pCur,nBufLen);
	Handler<<m_ChannelID<<m_SenderPeerID<<m_Flag;
	pCur += Handler.Size();

	Int32 iRet = 0;
	//copy PeerBM
	if(IsHasBmInfo())
	{
		iRet = m_BM.OutAsData(pCur, nBufLen);
		if(iRet <= 0)
			return 0;
		pCur += iRet;
	}

	PacketHandler Handler2(pCur,nBufLen);
	Handler2<<m_FriendCount;
	pCur += Handler2.Size();

	for(Int32 i=0; i<m_FriendCount; i++)
	{
		iRet = m_pFriendsInfo[i].MakeStream(pCur, nBufLen);
		if(iRet <= 0)
			return 0;
		pCur += iRet;
	}
	
	return pCur - ioBuf;
}
